using System;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Xsl;
using System.Xml.XPath;
using System.Xml;
using System.Resources;
using System.Globalization;

using SypConst.Garbage;
using SypEngine;
using SypEngine.SiteConfig;

using SypConst.Path;

namespace SypEngine.SiteConfig
{
    #region Serializable content

    [Serializable]
    public class XmlAlbum
    {
        public int id;
        public string title;
        public string link;
        public int selected;

        public XmlAlbum() { }
    }

    [Serializable]
    public class XmlCategory
    {
        public string title;
        public int id;
        public int selected = 0;
        public List<XmlAlbum> Albums = null;
       
        public XmlCategory(){}
    }
    
    [Serializable]
    public class XmlHeader
    {
       public string TitleSiteWeb;
       public string pathStylesheets;

        public XmlHeader() { }
    }

    [Serializable]
    public class XmlFooter
    {
        public string pathJavascript;
        public string sypIndexContentMapping;
        public XmlFooter() { }
    }

    [Serializable]
    public class Xmllink
    {
       public string title;
       public string name;
       public string href;

        public Xmllink() { }
    }

    [Serializable]
    public class XmlThumbnail
    {
        public string pathThumbnail;
        public string pathPicture;
        public string title;
        public int id;

        public XmlThumbnail() { }
    }

    [Serializable]
    public class XmlbodyPicture
    {
        public string linkNext;
        public string pathPicture;
        public string alt;
        public string author;
        public string linkContact;

        public XmlbodyPicture() { }
    }
    #endregion


    [XmlRoot("SypPage")]
    public class SypPage : SypGarbageObject
    {
        private string filename = null;
        private string fileLocalPath = null;
        private string fileOnlinePath = null;
        
        //admin page translations
        /*
        public string BUTTON_ADD_ALBUM = null;
        public string BUTTON_ADD_CATEGORY = null;
        public string BUTTON_OK = null;
        public string BUTTON_CANCEL = null;
        public string BUTTON_BROWSE = null;
        public string BUTTON_EDIT = null;
        public string BUTTON_DELETE = null;
        public string LABEL_ADD_ALBUM = null;
        public string LABEL_ADD_CATEGORY = null;
        public string LABEL_ADD_PICTURE = null;
        public string LABEL_DELETE_ALBUM = null;
        public string LABEL_DELETE_CATEGORY = null;
        public string LABEL_DELETE_DESCRP_ALBUM = null;
        public string LABEL_DELETE_DESCRP_CATEGORY = null;
		public string LABEL_DELETE_DESCRP_PICTURE = null;
        public string LABEL_TITRE = null;
        public string LABEL_FOLDER = null;
        public string LABEL_FILE = null;
		public string LABEL_LOADING = null;
        public string LABEL_PROGRESS_BAR_TITLE = null;
        public string LABEL_BUSY_TITLE = null;
        public string LABEL_BUSY_DESCR = null;
         */

        //public page translations
        public string MENU_ZIPPING_LNK = null;
        public string MENU_CONTACT_LNK = null;
        public string MENU_ABOUT_LNK = null;
        public string FOOTER_COPY = null;
        public string FOOTER_URL = null;


        
        public int PageId;
        public int SiteId;

        public int isLocal;
        
        public XmlHeader header = null;
        public List<Xmllink> topMenu = null;
        public List<XmlCategory> categories = null;
        public List<XmlThumbnail> thumbnails = null;
        public XmlbodyPicture bpicture = null;
        public XmlFooter footer = null;

        public SypPage() { }


        public SypPage(int PageId, int siteId, SetText OutputMethod, string language)
            : base(OutputMethod)
        {
            this.PageId = PageId;
            this.SiteId = siteId;
            ResourceManager resourceManager = new ResourceManager("Syp.Resources", GetType().Assembly);
            ResourceSet CurrentResource = resourceManager.GetResourceSet(new CultureInfo(SypGarbageConf.Instance().Language), true, false);

            if (CurrentResource != null)
            {
                //public page translations
                MENU_ZIPPING_LNK = CurrentResource.GetString("PageMenuZippingLnk");
                MENU_CONTACT_LNK = CurrentResource.GetString("PageMenuContactLnk");
                MENU_ABOUT_LNK = CurrentResource.GetString("PageMenuAboutLnk");
                FOOTER_COPY = CurrentResource.GetString("PageFooter");
                FOOTER_URL = CurrentResource.GetString("PageFooterUrl");
            }
        }

      

        private String UTF8ByteArrayToString(Byte[] characters)
        {
            UTF8Encoding encoding = new UTF8Encoding(true);
            String constructedString = encoding.GetString(characters);
            return (constructedString);
        }

        private XmlReader SerializeObjectIntoMem(Object pObject)
        {
            try
            {
                MemoryStream memoryStream = new MemoryStream();
                XmlSerializer xs = new XmlSerializer(typeof(SypPage), new Type[] { typeof(List<XmlCategory>), typeof(List<XmlAlbum>), typeof(List<Xmllink>), typeof(List<XmlThumbnail>), typeof(XmlCategory), typeof(XmlAlbum), typeof(XmlHeader), typeof(Xmllink), typeof(XmlbodyPicture), typeof(XmlThumbnail) });
                Encoding Utf8 = new UTF8Encoding(false);

                //xs.Serialize(memoryStream, pObject);

                XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Utf8);
                xs.Serialize(xmlTextWriter, pObject);
                memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
                memoryStream.Position = 0;

                SypGarbage.free(xs);
                SypGarbage.free(xmlTextWriter);
                XmlReader reader = XmlReader.Create(memoryStream);

                return reader;

            }
            catch (Exception e)
            {
                System.Console.WriteLine(e);
                return null;
            }
        }

        private void SerializeObjectWithXSLStylesheet(Object pObject, string stylesheetPath, string xmlDestinationFile)
        {
            try
            {
                //string XmlizedString = null;
                MemoryStream memoryStream = new MemoryStream();
                XmlSerializer xs = new XmlSerializer(typeof(SypPage), new Type[] { typeof(List<XmlCategory>), typeof(List<XmlAlbum>), typeof(List<Xmllink>), typeof(List<XmlThumbnail>), typeof(XmlCategory), typeof(XmlAlbum), typeof(XmlHeader), typeof(Xmllink), typeof(XmlbodyPicture), typeof(XmlThumbnail) });
                Encoding Utf8 = new UTF8Encoding(false);

                xs.Serialize(memoryStream, pObject);


                XmlDocument xmlDoc = new XmlDocument();
                memoryStream.Seek(0, SeekOrigin.Begin);
                xmlDoc.Load(memoryStream);

                String PItext = string.Format("type='text/xsl' href='{0}'", stylesheetPath);
                XmlProcessingInstruction newPI = xmlDoc.CreateProcessingInstruction("xml-stylesheet", PItext);
                xmlDoc.InsertAfter(newPI, xmlDoc.FirstChild);

                XmlTextWriter xmlWriter = new XmlTextWriter(xmlDestinationFile, Encoding.UTF8);
                xmlDoc.WriteTo(xmlWriter);
                xmlWriter.Flush();
            }
            catch (Exception e)
            {
                System.Console.WriteLine(e);
            }
        }

        private void XslCompiledTransforming(XmlReader xmlStream, string stylesheetPath, string htmlDestinationFile)
        {
            try
            {
                XslCompiledTransform myXslTrans = new XslCompiledTransform();
                myXslTrans.Load(stylesheetPath);

                //Generate Page
                XPathDocument myXPathDoc = new XPathDocument(xmlStream);
                XmlWriter myWriter = XmlWriter.Create(htmlDestinationFile, myXslTrans.OutputSettings);
                myXslTrans.Transform(myXPathDoc, null, myWriter);
                myWriter.Close();

                //Delete xml files getting from serialization
                SypGarbage.free(myWriter);
                SypGarbage.free(myXPathDoc);
                SypGarbage.free(myXslTrans);
            }
            catch (Exception e)
            {
                OutputMethod("[XslCompiledTransforming - Error catched] : " + e.ToString(), Output.ERROR);
            }
        }

        public void GenerateSypPage()
        {
            try
            {
                string XsltPath = SypPathHandler.GetPath(SypPathMode.LOCAL, SypPathRef.XSLT_PAGE, null, SiteId);

                isLocal = 1;
                //filename = SypPathHandler.GetPath(SypPathMode.ONLINE, SypPathRef.XSLT_PAGENAME_TYPE_0, null, -1, -1, PageId);
                //SerializeObjectWithXSLStylesheet(this, SypPathHandler.GetPath(SypPathMode.LOCAL, SypPathRef.XSLT_PAGE_RELATIF, null, null), fileLocalPath + filename);
                XslCompiledTransforming(SerializeObjectIntoMem(this),  XsltPath, fileLocalPath + filename);

                isLocal = 0;
                //filename = SypPathHandler.GetPath(SypPathMode.ONLINE, SypPathRef.XSLT_PAGENAME_TYPE_0, null, -1, -1, PageId);
                XslCompiledTransforming(SerializeObjectIntoMem(this), XsltPath, fileOnlinePath + filename);


            }
            catch (Exception e) {
                OutputMethod("[GenerateSypPage - Error catched] : " + e.ToString(), Output.ERROR);
            }
        }

        private string FormatJsonContentMapping(SypSite mySite)
        {
            string JsonData = "var _sypIndexContentMapping = {categories:[";
            List<Category> _categoryList = mySite.CategorysList;
            foreach (Category _category in _categoryList)
            {
                JsonData += "{";
                JsonData += "label : '" + _category.CategoryTitle + "',";
                JsonData += "sypId : " + _category.Id + ",";
                JsonData += "albums:[";
                if (_category.AlbumList != null)
                {
                    foreach (Album _album in _category.AlbumList)
                    {
                        JsonData += "{";
                        JsonData += "label : '" + _album.AlbumTitle + "',";
                        JsonData += "sypId : " + _album.id;
                        JsonData += "},";
                    }
                    if (_category.AlbumList.Count > 0)
                        JsonData = JsonData.Substring(0, JsonData.Length - 1);
                }
                JsonData += "]},";
            }
            if (_categoryList.Count > 0)
                JsonData = JsonData.Substring(0, JsonData.Length - 1);
            JsonData += "]}";
            return JsonData;
        }

        public void LoadPage(SypSite mySite)
        {
            List<Category> CategoryList = mySite.CategorysList;
            List<Picture> Pictures = null;

            ResourceManager resourceManager = new ResourceManager("Syp.Resources", GetType().Assembly);
            ResourceSet CurrentResource = resourceManager.GetResourceSet(new CultureInfo(SypGarbageConf.Instance().Language), true, false);

            filename = SypPathHandler.GetPath(SypPathMode.ONLINE, SypPathRef.XSLT_PAGENAME_TYPE_0, null, -1, -1, PageId);

            fileLocalPath = SypPathHandler.GetPath(SypPathMode.LOCAL, SypPathRef.CATEGORIES_FOLDER, null, mySite.SiteId);

            fileOnlinePath = SypPathHandler.GetPath(SypPathMode.LOCAL, SypPathRef.TOUP_FOLDER, null, mySite.SiteId);

            header = new XmlHeader();
            header.TitleSiteWeb = mySite.SiteTitle;
            header.pathStylesheets = SypPathHandler.GetPath(SypPathMode.ONLINE, SypPathRef.XSLT_PATH_STYLESHEET, null);
            footer = new XmlFooter();

            footer.pathJavascript = SypPathHandler.GetPath(SypPathMode.ONLINE, SypPathRef.XSLT_PATH_JAVASCRIPT, null);
            footer.sypIndexContentMapping = FormatJsonContentMapping(mySite);


            //generateLeftMenu
            if (categories == null)
                categories = new List<XmlCategory>();
            foreach (Category category in CategoryList)
            {
                XmlCategory currentXmlCat = new XmlCategory();
                currentXmlCat.id = category.Id;
                currentXmlCat.title = category.CategoryTitle;
                categories.Add(currentXmlCat);

                if (currentXmlCat.Albums == null)
                    currentXmlCat.Albums = new List<XmlAlbum>();


                if (category.AlbumList != null)
                {
                    foreach (Album album in category.AlbumList)
                    {
                        XmlAlbum currentXmlAlb = new XmlAlbum();
                        currentXmlAlb.id = album.id;
                        currentXmlAlb.title = album.AlbumTitle;
                        //Album Page
                        if (PageId != album.id)
                        {
                            currentXmlAlb.link = SypPathHandler.GetPath(SypPathMode.ONLINE, SypPathRef.XSLT_ALBUM_CURRENT_LNK, null, -1, -1, album.id);
                            currentXmlAlb.selected = 0;
                        }
                        else
                        {
                            //                            fileOnlinePath += "category" + category.Id + "/album" + album.id + "/";
                            //fileLocalPath += SypGarbage.CATEGORY_PREF_DIR + category.Id + "/" + SypGarbage.ALBUM_PREF_DIR + PageId + "/";
                            //fileLocalPath += SypPathHandler.GetPath(SypPathMode.ONLINE, SypPathRef.XSLT_FILE_PATH, null, -1, category.Id, PageId);
                            currentXmlAlb.link = SypPathHandler.GetPath(SypPathMode.ONLINE, SypPathRef.XSLT_ALBUM_CURRENT_LNK, null, -1, -1, PageId);
                            currentXmlAlb.selected = 1;
                            Pictures = album.PicturesList;
                            currentXmlCat.selected = 1;
                        }

                        currentXmlCat.Albums.Add(currentXmlAlb);
                    }
                }
            }
            //generateTopMenu
            //album page
            if (topMenu == null)
                topMenu = new List<Xmllink>();

            Xmllink ArchivesLnk = new Xmllink();
            Xmllink AboutLnk = new Xmllink();
            Xmllink ContactLnk = new Xmllink();

            ArchivesLnk.name = CurrentResource.GetString("PageMenuZippingLnk");
            AboutLnk.name = CurrentResource.GetString("PageMenuAboutLnk");
            ContactLnk.name = CurrentResource.GetString("PageMenuContactLnk");

            ArchivesLnk.title = CurrentResource.GetString("PageMenuZippingLnk");
            AboutLnk.title = CurrentResource.GetString("PageMenuAboutLnk");
            ContactLnk.title = CurrentResource.GetString("PageMenuContactLnk");

            //ArchivesLnk.href = "../../../" + SypGarbage.ZIP_FOLDER + PageId + SypGarbage.ZIP_EXTENSION;
            ArchivesLnk.href = SypPathHandler.GetPath(SypPathMode.ONLINE, SypPathRef.XSLT_ARCHIVE_LNK, null, -1, -1, PageId);
            //AboutLnk.href = "../../../" + SypGarbage.ABOUT_PAGE_INDEX;
            AboutLnk.href = SypPathHandler.GetPath(SypPathMode.ONLINE, SypPathRef.XSLT_ABOUT_LNK, null);
            ContactLnk.href = SypPathHandler.GetPath(SypPathMode.ONLINE, SypPathRef.XSLT_CONTACT_LNK, null);

            topMenu.Add(AboutLnk);
            topMenu.Add(ContactLnk);

            if (Pictures != null)
            {
                foreach (Picture pict in Pictures)
                {
                    XmlThumbnail myThumbnail = new XmlThumbnail();
                    myThumbnail.title = pict.Title;
                    myThumbnail.id = pict.Id;
                    //myThumbnail.pathThumbnail = "../../../" + SypGarbage.THUMBNAILS_FOLDER + SypGarbage.THUMBNAIL_PREF + pict.Id + SypGarbage.THUMBNAIL_EXTENSION;
                    myThumbnail.pathThumbnail = SypPathHandler.GetPath(SypPathMode.ONLINE, SypPathRef.XSLT_PATH_THUMBNAIL, null, -1, -1, -1, pict.Id);
                    //myThumbnail.pathPicture = "../../../" + SypGarbage.PICTURES_FOLDER + SypGarbage.PICTURE_PREF + pict.Id + SypGarbage.PICTURE_EXTENSION;
                    myThumbnail.pathPicture = SypPathHandler.GetPath(SypPathMode.ONLINE, SypPathRef.XSLT_PATH_PICTURE, null, -1, -1, -1, pict.Id);
                    //myThumbnail.href = SypGarbage.PICTURE_PREF + pict.Id + SypGarbage.PAGE_EXTENSION;
                    //myThumbnail.href = SypPathHandler.GetPath(SypPathMode.ONLINE, SypPathRef.XSLT_THUMBNAIL_LNK, null, -1, -1, -1, pict.Id);
                    if (thumbnails == null)
                        thumbnails = new List<XmlThumbnail>();
                    thumbnails.Add(myThumbnail);
                }
            }

        }

    }


}




